package com.kurt.service.impl;

import com.kurt.dto.DriverDTO;
import com.kurt.dto.VehicleDTO;
import com.kurt.dto.create.DataPermissionCreateRequest;
import com.kurt.dto.create.VehicleCreateRequest;
import com.kurt.dto.query.VehicleQueryRequest;
import com.kurt.dto.update.VehicleUpdateRequest;
import com.kurt.entity.*;
import com.kurt.repository.*;
import com.kurt.service.DataPermissionService;
import com.kurt.service.VehicleService;
import com.kurt.util.DataPermissionUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 车辆服务实现类
 * 实现车辆相关的业务逻辑
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class VehicleServiceImpl extends BaseServiceImpl<SysVehicle, Long> implements VehicleService {

    private final SysVehicleRepository vehicleRepository;
    private final SysVehicleExtensionRepository vehicleExtensionRepository;
    private final SysOrganizationRepository organizationRepository;
    private final SysVehicleDriverRepository vehicleDriverRepository;
    private final SysDriverRepository driverRepository;
    private final SysDriverExtensionRepository driverExtensionRepository;
    private final DataPermissionUtil dataPermissionUtil;
    private final DataPermissionService dataPermissionService;

    @Override
    protected SysVehicleRepository getRepository() {
        return vehicleRepository;
    }

    @Override
    protected SysVehicleRepository getSpecificationExecutor() {
        return vehicleRepository;
    }

    @Override
    @Transactional
    public VehicleDTO createVehicle(VehicleCreateRequest createRequest) {
        log.info("创建车辆: {}", createRequest.getLicensePlate());

        // 检查车牌号是否已存在
        if (vehicleRepository.findByLicensePlate(createRequest.getLicensePlate()).isPresent()) {
            throw new RuntimeException("车牌号已存在");
        }

        // 检查SIM卡号是否已存在
        if (StringUtils.hasText(createRequest.getSimCardNo()) &&
                vehicleRepository.findBySimCardNo(createRequest.getSimCardNo()).isPresent()) {
            throw new RuntimeException("SIM卡号已存在");
        }

        // 创建车辆实体
        SysVehicle vehicle = new SysVehicle();
        BeanUtils.copyProperties(createRequest, vehicle);
        vehicle.setCreateTime(LocalDateTime.now());
        vehicle.setUpdateTime(LocalDateTime.now());

        // 保存车辆
        vehicle = vehicleRepository.save(vehicle);

        // 创建车辆扩展信息
        if (createRequest.getVehicleExtension() != null) {
            SysVehicleExtension extension = new SysVehicleExtension();
            extension.setId(vehicle.getId());
            BeanUtils.copyProperties(createRequest.getVehicleExtension(), extension);
            extension.setCreateTime(LocalDateTime.now());
            extension.setUpdateTime(LocalDateTime.now());
            vehicleExtensionRepository.save(extension);
        }

        // 自动给创建人赋予该车辆的数据权限
        Long currentUserId = createRequest.getLoginUserId();
        if (currentUserId != null) {
            dataPermissionService.createDataPermission(new DataPermissionCreateRequest(currentUserId, "vehicle", vehicle.getId()));
            log.info("自动为创建人{}赋予车辆{}的数据权限", currentUserId, vehicle.getId());
        } else {
            log.warn("创建车辆时无法获取当前用户ID，跳过自动赋予数据权限");
        }

        log.info("车辆创建成功: {}", vehicle.getLicensePlate());
        return convertToVehicleDTO(vehicle);
    }

    @Override
    @Transactional
    public VehicleDTO updateVehicle(VehicleUpdateRequest updateRequest) {
        log.info("更新车辆: {}", updateRequest.getId());

        // 查找车辆
        SysVehicle vehicle = getById(updateRequest.getId());

        // 检查车牌号是否已存在（排除自己）
        if (StringUtils.hasText(updateRequest.getLicensePlate()) &&
                !updateRequest.getLicensePlate().equals(vehicle.getLicensePlate()) &&
                vehicleRepository.findByLicensePlate(updateRequest.getLicensePlate()).isPresent()) {
            throw new RuntimeException("车牌号已存在");
        }

        // 检查SIM卡号是否已存在（排除自己）
        if (StringUtils.hasText(updateRequest.getSimCardNo()) &&
                !updateRequest.getSimCardNo().equals(vehicle.getSimCardNo()) &&
                vehicleRepository.findBySimCardNo(updateRequest.getSimCardNo()).isPresent()) {
            throw new RuntimeException("SIM卡号已存在");
        }

        // 更新车辆信息
        if (StringUtils.hasText(updateRequest.getLicensePlate())) {
            vehicle.setLicensePlate(updateRequest.getLicensePlate());
        }
        if (StringUtils.hasText(updateRequest.getSimCardNo())) {
            vehicle.setSimCardNo(updateRequest.getSimCardNo());
        }
        if (StringUtils.hasText(updateRequest.getDeviceId())) {
            vehicle.setDeviceId(updateRequest.getDeviceId());
        }
        if (StringUtils.hasText(updateRequest.getDeviceType())) {
            vehicle.setDeviceType(updateRequest.getDeviceType());
        }
        if (StringUtils.hasText(updateRequest.getVehicleType())) {
            vehicle.setVehicleType(updateRequest.getVehicleType());
        }
        if (updateRequest.getOrganizationId() != null) {
            vehicle.setOrganizationId(updateRequest.getOrganizationId());
        }
        if (updateRequest.getStatus() != null) {
            vehicle.setStatus(updateRequest.getStatus());
        }
        if (StringUtils.hasText(updateRequest.getRemark())) {
            vehicle.setRemark(updateRequest.getRemark());
        }
        vehicle.setUpdateTime(LocalDateTime.now());

        // 保存车辆
        vehicle = vehicleRepository.save(vehicle);

        // 更新车辆扩展信息
        if (updateRequest.getVehicleExtension() != null) {
            Optional<SysVehicleExtension> extensionOpt = vehicleExtensionRepository.findById(vehicle.getId());
            if (extensionOpt.isPresent()) {
                SysVehicleExtension extension = extensionOpt.get();
                BeanUtils.copyProperties(updateRequest.getVehicleExtension(), extension);
                extension.setUpdateTime(LocalDateTime.now());
                vehicleExtensionRepository.save(extension);
            } else {
                // 创建新的扩展信息
                SysVehicleExtension extension = new SysVehicleExtension();
                extension.setId(vehicle.getId());
                BeanUtils.copyProperties(updateRequest.getVehicleExtension(), extension);
                extension.setCreateTime(LocalDateTime.now());
                extension.setUpdateTime(LocalDateTime.now());
                vehicleExtensionRepository.save(extension);
            }
        }

        log.info("车辆更新成功: {}", vehicle.getLicensePlate());
        return convertToVehicleDTO(vehicle);
    }

    @Override
    public VehicleDTO getVehicleById(Long id) {
        SysVehicle vehicle = getById(id);
        return convertToVehicleDTO(vehicle);
    }

    @Override
    public Page<VehicleDTO> getVehiclePage(VehicleQueryRequest queryRequest) {
        // 构建分页参数
        Sort sort = Sort.by(Sort.Direction.fromString(queryRequest.getOrderDirection()), queryRequest.getOrderBy());
        Pageable pageable = PageRequest.of(queryRequest.getPageNum() - 1, queryRequest.getPageSize(), sort);

        // 构建查询条件
        Specification<SysVehicle> spec = buildVehicleSpecification(queryRequest);

        // 执行分页查询
        Page<SysVehicle> vehiclePage = vehicleRepository.findAll(spec, pageable);

        // 转换为DTO
        return vehiclePage.map(this::convertToVehicleDTO);
    }

    @Override
    public List<VehicleDTO> getVehicleList(VehicleQueryRequest queryRequest) {
        // 构建查询条件
        Specification<SysVehicle> spec = buildVehicleSpecification(queryRequest);

        // 执行查询
        List<SysVehicle> vehicles = vehicleRepository.findAll(spec);

        // 转换为DTO
        return vehicles.stream().map(this::convertToVehicleDTO).collect(Collectors.toList());
    }

    @Override
    @Transactional
    public boolean deleteVehicle(Long id) {
        log.info("删除车辆: {}", id);

        // 删除车辆驾驶员关联
        vehicleDriverRepository.deleteByVehicleId(id);

        // 删除车辆扩展信息
        vehicleExtensionRepository.deleteById(id);

        // 删除车辆
        vehicleRepository.deleteById(id);

        log.info("车辆删除成功: {}", id);
        return true;
    }

    @Override
    @Transactional
    public boolean deleteVehicles(List<Long> ids) {
        log.info("批量删除车辆: {}", ids);

        for (Long id : ids) {
            deleteVehicle(id);
        }

        log.info("批量删除车辆成功: {}", ids);
        return true;
    }

    @Override
    public List<VehicleDTO> getVehiclesByOrganizationId(Long organizationId, Long userId) {
        // 数据权限过滤 - 只查询用户有权限的车辆
        if (userId == null) {
            log.warn("用户未登录，无法获取车辆数据");
            return new ArrayList<>();
        }

        List<Long> authorizedVehicleIds = dataPermissionUtil.getAuthorizedResourceIds(userId, "vehicle");
        if (authorizedVehicleIds.isEmpty() || authorizedVehicleIds.contains(-1L)) {
            log.warn("用户{}没有车辆数据权限", userId);
            return new ArrayList<>();
        }

        // 先根据组织ID查询车辆
        List<SysVehicle> vehicles = vehicleRepository.findByOrganizationId(organizationId);

        // 再根据数据权限过滤
        List<SysVehicle> filteredVehicles = vehicles.stream()
                .filter(vehicle -> authorizedVehicleIds.contains(vehicle.getId()))
                .collect(Collectors.toList());

        log.info("用户{}查询组织{}的车辆，原始数量: {}, 权限过滤后数量: {}",
                userId, organizationId, vehicles.size(), filteredVehicles.size());

        return filteredVehicles.stream().map(this::convertToVehicleDTO).collect(Collectors.toList());
    }

    @Override
    public boolean existsByLicensePlate(String licensePlate) {
        return vehicleRepository.findByLicensePlate(licensePlate).isPresent();
    }

    @Override
    public boolean existsByLicensePlateAndIdNot(String licensePlate, Long excludeId) {
        Optional<SysVehicle> vehicleOpt = vehicleRepository.findByLicensePlate(licensePlate);
        return vehicleOpt.isPresent() && !vehicleOpt.get().getId().equals(excludeId);
    }

    @Override
    public boolean existsBySimCardNo(String simCardNo) {
        return vehicleRepository.findBySimCardNo(simCardNo).isPresent();
    }

    @Override
    public boolean existsBySimCardNoAndIdNot(String simCardNo, Long excludeId) {
        Optional<SysVehicle> vehicleOpt = vehicleRepository.findBySimCardNo(simCardNo);
        return vehicleOpt.isPresent() && !vehicleOpt.get().getId().equals(excludeId);
    }

    @Override
    @Transactional
    public boolean updateStatus(Long id, Integer status) {
        log.info("更新车辆状态: id={}, status={}", id, status);

        SysVehicle vehicle = getById(id);
        vehicle.setStatus(status);
        vehicle.setUpdateTime(LocalDateTime.now());
        vehicleRepository.save(vehicle);

        log.info("车辆状态更新成功: id={}, status={}", id, status);
        return true;
    }

    @Override
    @Transactional
    public boolean updateMileage(Long id, java.math.BigDecimal mileage) {
        log.info("更新车辆里程: id={}, mileage={}", id, mileage);

        Optional<SysVehicleExtension> extensionOpt = vehicleExtensionRepository.findById(id);
        if (extensionOpt.isPresent()) {
            SysVehicleExtension extension = extensionOpt.get();
            extension.setMileage(mileage);
            extension.setUpdateTime(LocalDateTime.now());
            vehicleExtensionRepository.save(extension);
        }

        log.info("车辆里程更新成功: id={}, mileage={}", id, mileage);
        return true;
    }

    /**
     * 构建车辆查询条件
     *
     * @param queryRequest 查询请求
     * @return 查询条件
     */
    private Specification<SysVehicle> buildVehicleSpecification(VehicleQueryRequest queryRequest) {
        return (root, query, cb) -> {
            List<jakarta.persistence.criteria.Predicate> predicates = new ArrayList<>();

            // 数据权限过滤 - 只查询用户有权限的车辆
            Long currentUserId = queryRequest.getLoginUserId();
            System.out.println("当前用户ID: " + currentUserId);
            if (currentUserId != null) {
                List<Long> authorizedVehicleIds = dataPermissionUtil.getAuthorizedResourceIds(currentUserId, "vehicle");
                predicates.add(root.get("id").in(authorizedVehicleIds));
            }

            // 车牌号模糊查询
            if (StringUtils.hasText(queryRequest.getLicensePlate())) {
                predicates.add(cb.like(root.get("licensePlate"), "%" + queryRequest.getLicensePlate() + "%"));
            }

            // SIM卡号模糊查询
            if (StringUtils.hasText(queryRequest.getSimCardNo())) {
                predicates.add(cb.like(root.get("simCardNo"), "%" + queryRequest.getSimCardNo() + "%"));
            }

            // 终端ID模糊查询
            if (StringUtils.hasText(queryRequest.getDeviceId())) {
                predicates.add(cb.like(root.get("deviceId"), "%" + queryRequest.getDeviceId() + "%"));
            }

            // 设备类型查询
            if (StringUtils.hasText(queryRequest.getDeviceType())) {
                predicates.add(cb.equal(root.get("deviceType"), queryRequest.getDeviceType()));
            }

            // 车辆类型查询
            if (StringUtils.hasText(queryRequest.getVehicleType())) {
                predicates.add(cb.equal(root.get("vehicleType"), queryRequest.getVehicleType()));
            }

            // 组织ID查询
            if (queryRequest.getOrganizationId() != null) {
                predicates.add(cb.equal(root.get("organizationId"), queryRequest.getOrganizationId()));
            }

            // 状态查询
            if (queryRequest.getStatus() != null) {
                predicates.add(cb.equal(root.get("status"), queryRequest.getStatus()));
            }

            // 创建时间范围查询
            if (StringUtils.hasText(queryRequest.getCreateTimeStart())) {
                predicates.add(cb.greaterThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeStart())));
            }
            if (StringUtils.hasText(queryRequest.getCreateTimeEnd())) {
                predicates.add(cb.lessThanOrEqualTo(root.get("createTime"),
                        LocalDateTime.parse(queryRequest.getCreateTimeEnd())));
            }

            return cb.and(predicates.toArray(new jakarta.persistence.criteria.Predicate[0]));
        };
    }

    /**
     * 转换车辆实体为DTO
     *
     * @param vehicle 车辆实体
     * @return 车辆DTO
     */
    private VehicleDTO convertToVehicleDTO(SysVehicle vehicle) {
        VehicleDTO vehicleDTO = new VehicleDTO();
        BeanUtils.copyProperties(vehicle, vehicleDTO);

        // 获取车辆扩展信息
        Optional<SysVehicleExtension> extensionOpt = vehicleExtensionRepository.findById(vehicle.getId());
        if (extensionOpt.isPresent()) {
            VehicleDTO.VehicleExtensionDTO extensionDTO = new VehicleDTO.VehicleExtensionDTO();
            BeanUtils.copyProperties(extensionOpt.get(), extensionDTO);

            // 获取组织名称
            if (extensionOpt.get().getOrganizationId() != null) {
                Optional<SysOrganization> orgOpt = organizationRepository.findById(extensionOpt.get().getOrganizationId());
                if (orgOpt.isPresent()) {
                    extensionDTO.setOrganizationName(orgOpt.get().getName());
                }
            }

            vehicleDTO.setVehicleExtension(extensionDTO);
        }

        // 获取关联的驾驶员列表（包含扩展数据）
        List<SysVehicleDriver> vehicleDrivers = vehicleDriverRepository.findByVehicleId(vehicle.getId());
        List<DriverDTO> drivers = vehicleDrivers.stream()
                .map(vd -> {
                    Optional<SysDriver> driverOpt = driverRepository.findById(vd.getDriverId());
                    if (driverOpt.isPresent()) {
                        DriverDTO driverDTO = new DriverDTO();
                        BeanUtils.copyProperties(driverOpt.get(), driverDTO);

                        // 获取驾驶员扩展信息
                        Optional<SysDriverExtension> driverExtensionOpt = driverExtensionRepository.findById(driverOpt.get().getId());
                        if (driverExtensionOpt.isPresent()) {
                            DriverDTO.DriverExtensionDTO extensionDTO = new DriverDTO.DriverExtensionDTO();
                            BeanUtils.copyProperties(driverExtensionOpt.get(), extensionDTO);
                            driverDTO.setDriverExtension(extensionDTO);
                        }

                        return driverDTO;
                    }
                    return null;
                })
                .filter(driver -> driver != null)
                .collect(Collectors.toList());
        vehicleDTO.setDrivers(drivers);

        return vehicleDTO;
    }
}
